/******************************************************************************
 *  _____     _____
 *  \  __\    \  __\
 *   \ \_\\    \ \_\\
 *    \  __\SS  \  __\roject
 *     \_\       \_\
 *
 * Mateusz Maciąg, Rafał Urbański
 * Komputerowe Systemy Sterowania
 *****************************************************************************/

#ifndef GAINCONTROLLER_H
#define GAINCONTROLLER_H

#include "ControllerBase.h"

// Przestrzeń nazw
namespace RafMat
{
namespace SimEngine
{

/**
    Klasa regulatora typu P.

    Regulator P jest najprostszym regulatorem dziedziczącym po klasie ControllerBase.
    Charakteryzuje się określonym wzmocnieniem uchybu regulacji, zgodnie ze wzorem:

    y(i) = gain * e(i)
*/
class GainController : public ControllerBase
{
public:
    /**
        Konstruktor regulatora P.
        Konstruktor wiąże regulator z konkretnym obiektem symulatora.
        Domyślnie jest to regulator o wzmocnieniu jednostkowym

        \param [in] isim Obiekt symulatora-właściciela tego regulatora.
        \param [in] gain Wzmocnienie regulatora (parametr k).
    */
    explicit GainController(SimInterface::ISimulator &isim, double gain = 1);

    //
    // Implementacja IConfigurable
    //

    /**
        Funkcja ustawiająca parametry regulatora P za pomocą łańcuchów znakowych.

        Wspierane parametry:
        - gain - liczba rzeczywista

        \param [in] param Parametr, który chcemy zmienić (jeden z wymienionych).
        \param [in] value Wartość, którą przypisujemy parametrowi.
        \return True jeśli operacja się powiodła.
        \throws std::logic_error, gdy wykryty zostanie błąd (argumentu lub strumienia danych).
    */
    bool setParameter(const std::string& param, const std::string& value) throw(std::logic_error);

    /**
        Funkcja pobiera parametry regulatora P w postaci łańcuchów znakowych.

        Wspierane parametry są takie same jak w setParameter().

        \param [in] param Parametr, który chcemy odczytać.
        \return Łańcuch reprezentujący wartość parametru.
        \throws std::logic_error, gdy wykryty zostanie błąd (argumentu lub strumienia danych).
    */
    std::string getParameter(const std::string& param) const throw(std::logic_error);

    /**
        Resetuje regulator (dla typu P nie robi nic).
    */
    void reset() {}

protected:

    /**
        Realizuje krok regulacji proporcjonalnej.

        Funkcja implementuje abstrakcyjną metodę z klasy bazowej ControllerBase.
        Realizuje równanie wyjścia regulatora P.

        \param [in] setPoint Wartość zadana.
        \param [in] processVar Wartość zmiennej procesowej (np. ze sprzężenia zwrotnego).
        \return Wartość wyjścia regulatora.
    */
    double simulateControllerStep(double setPoint, double processVar);

    SimFile::ConfigWriter& dumpSpecificPar(SimFile::ConfigWriter& o) const;

private:
    // Stałe pomocnicze:
    static const std::string CONF_GAIN;

    double m_gain;      ///< Wzmocnienie regulatora P.
};

}
}

#endif // GAINCONTROLLER_H
